<template>
  <div>
    <el-form label-width="80px" size="small" >
<!--      <el-form-item label="异步">-->
<!--        <el-switch v-model="bpmnFormData.async" active-text="是" inactive-text="否" @change="updateElementTask('async')"/>-->
<!--      </el-form-item>-->
      <el-form-item label="审批指定">
        <el-radio-group size="mini" v-model="bpmnFormData.assignType" @change="changeAssignType" :disabled="firstUserTask || multiInstanceTask">
          <el-radio v-for="item in assignTypeOption" :key="item.key" :label="item.key">{{item.label}}</el-radio>
        </el-radio-group>
      </el-form-item>

      <el-form-item label-width="15px" style="margin-bottom: 5px">
        <el-button-group class="ml-4">
          <template v-for="button in assignButtonList">
            <el-button :key="button.assignType" :disabled="firstUserTask || multiInstanceTask"
                       v-show="button.show || button.assignType === bpmnFormData.assignType"
                       size="mini" :type="button.buttonType" :icon="button.icon"
                       @click="handleAssignButtonClick(button.assignType)">
              {{ button.text }}
            </el-button>
          </template>
        </el-button-group>
      </el-form-item>
      <el-form-item label-width="15px" style="margin-bottom: 5px">
        <template v-if="expType === 'writeExp'" >
          <div class="inline-box">
            <div v-for="(assign, index) in selectAssignList" :key="index">
              <el-input
                v-if="editTag[index]"
                v-model="assign.value"
                :ref="'editInput' + index"
                size="small"
                @keyup.enter.native="handleEditableInputConfirm(assign, index)"
                @change="handleEditableInputConfirm(assign, index)"
                @blur="handleEditableInputBlur(assign, index)"
              ></el-input>
              <el-tag
                v-else
                style="margin-right: 5px;"
                :closable="!firstUserTask && !multiInstanceTask"
                effect="plain"
                size="small"
                @click="showEditTagInput(index)"
                @close="handleAssignClose(assign)"
              >
                {{assign.value}}
              </el-tag>
            </div>
          </div>
        </template>
        <template v-else>
          <el-tag
            style="margin-right: 5px;"
            v-for="assign in selectAssignList"
            :key="assign.id"
            :closable="!firstUserTask && !multiInstanceTask"
            effect="plain"
            size="small"
            @close="handleAssignClose(assign)"
          >
            {{assign.name}}
          </el-tag>
        </template>
      </el-form-item>
      <el-divider v-if="!firstUserTask"/>
      <el-form-item label="按钮配置" v-show="!firstUserTask">
        <el-checkbox-group v-model="bpmnFormData.buttonList" @change="handleCheckedButtonsChange">
          <el-checkbox v-for="button in buttonOption" :label="button.id" :key="button.id">
            <span> {{ button.label }}</span>
            <span style="color: #696767;padding-left: 3px" @click.stop.prevent="editButton(button)">
              <i class="el-icon-edit"></i>
            </span>
          </el-checkbox>
        </el-checkbox-group>
      </el-form-item>

      <!--   抄送信息     -->
      <copy-panel :id="id" v-show="!firstUserTask"/>

      <el-form-item label="退回设置" label-width="95px" v-if="!firstUserTask && !multiInstanceTask">
        <el-switch
          class="custom-switch"
          @change="updateElementTask('autoSkip')"
          v-model="bpmnFormData.autoSkip"
          active-text="重新提交跳过中间节点"
          inactive-text="重新提交不跳过中间节点"
          active-value="true"
          inactive-value="false">
        </el-switch>
        <el-tooltip placement="top" content="a,b,c三个节点, c退回至a, a节点重新提交任务后直接到c节点">
          <i style="margin-left: 5px;" class="el-icon-warning-outline" />
        </el-tooltip>
      </el-form-item>

<!--      <el-form-item label="优先级">-->
<!--        <el-input v-model="bpmnFormData.priority" @change="updateElementTask('priority')"/>-->
<!--      </el-form-item>-->
      <el-form-item label-width="95px" v-if="!firstUserTask && !multiInstanceTask">
        <template slot="label">
              <span>
                 到期时间
                 <el-tooltip placement="top">
                    <template slot="content">
                       <div>
                         dueDate属性只是标识该用户任务何时过期，但过期后不会自动完成。
                         <br/>
                         在flowable中，用户任务过期时间存储在 ACT_RU_TASK 表的 DUE_DATE 字段中，
                         <br/>
                         flowable提供了基于过期时间进行查询的API。
                       </div>
                    </template>
                    <i class="el-icon-question" />
                 </el-tooltip>
              </span>
        </template>
          <el-select v-model="bpmnFormData.timerType" class="m-2 select-margin" placeholder="请选择到期时间类型" clearable @change="handleTimerChange" @clear="handleClearDueDate">
            <el-option
              v-for="item in timerList"
              :key="item.value"
              :label="item.label"
              :value="item.value"
            />
          </el-select>
          <template v-if="bpmnFormData.timerType === 'timeDuration'">
            <!--到期时间设置-->
            <el-popover placement="top" trigger="click" title="到期时间设置" width="320px" append-to-body>
              <el-input-number controls-position="right" data-unit="年" :min="0" v-model="bpmnFormData.timeDuration.years" class="my-el-input-number" @change="changeTimeDuration" />
              <el-input-number controls-position="right" data-unit="月" :min="0" v-model="bpmnFormData.timeDuration.months" class="my-el-input-number" @change="changeTimeDuration" />
              <el-input-number controls-position="right" data-unit="日" :min="0" v-model="bpmnFormData.timeDuration.days" class="my-el-input-number" @change="changeTimeDuration"/>
              <br/>
              <el-input-number controls-position="right" data-unit="时" :min="0" v-model="bpmnFormData.timeDuration.hours" class="my-el-input-number" @change="changeTimeDuration"/>
              <el-input-number controls-position="right" data-unit="分" :min="0" v-model="bpmnFormData.timeDuration.minutes" class="my-el-input-number" @change="changeTimeDuration"/>
              <el-input-number controls-position="right" data-unit="秒" :min="0" v-model="bpmnFormData.timeDuration.seconds" class="my-el-input-number" @change="changeTimeDuration"/>

              <template slot="reference">
                <el-input v-model="bpmnFormData.dueDate" placeholder="请填写到期时间">
                  <template slot="append">
                    <el-button icon="el-icon-setting" ></el-button>
                  </template>
                </el-input>
              </template>
            </el-popover>
          </template>
          <template v-else-if="bpmnFormData.timerType === 'timeDate'">
            <el-date-picker v-model="bpmnFormData.dueDate" format="yyyy-MM-ddTHH:mm:ss" value-format="yyyy-MM-ddTHH:mm:ss" type="datetime" placeholder="请选择到期时间" @change="updateElementTask('dueDate')"/>
          </template>
          <template v-else>
            <el-input v-model="bpmnFormData.dueDate" placeholder="请填写表达式" @change="updateElementTask('dueDate')"/>
          </template>
      </el-form-item>
      <el-form-item label="跳过任务" label-width="95px" v-if="!firstUserTask && !multiInstanceTask">
        <el-input size="mini" v-model="bpmnFormData.skipExpression" placeholder="示例: ${assignee == 'leader'}" @change="updateElementTask('skipExpression')"/>
      </el-form-item>
    </el-form>

    <!--更新按钮信息-->
    <el-dialog title="按钮配置" :visible.sync="buttonDialogVisible" width="500px" append-to-body>
      <el-form :model="buttonForm" label-width="80px">
        <el-form-item label="按钮标签" prop="label">
          <el-input v-model="buttonForm.label" placeholder="请输入按钮标签" />
        </el-form-item>
        <el-form-item label="按钮图标" prop="icon">
          <el-select filterable placeholder="请选择图标" v-model="buttonForm.icon">
            <el-option
              v-for="item in iconList"
              :key="item.value"
              :label="item.label"
              :value="item.value"
            >
                <span style="float: left">
                  <i :class="item.label"></i>
                </span>
              <span style="float: right; color: #8492a6; font-size: 13px">{{ item.label }}</span>
            </el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="按钮类型" prop="type">
          <el-select v-model="buttonForm.type" placeholder="请选择按钮类型">
            <el-option
              v-for="(item , index) in buttonTypeOptions"
              :key="index"
              :label="item"
              :value="item"
            />
          </el-select>
        </el-form-item>
        <el-form-item label="按钮尺寸" prop="size">
          <el-select v-model="buttonForm.size" placeholder="请选择按钮尺寸">
            <el-option
              v-for="(item , index) in buttonSizeOptions"
              :key="index"
              :label="item"
              :value="item"
            />
          </el-select>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button size="small" @click="buttonDialogVisible = false">取 消</el-button>
        <el-button size="small" type="primary" @click="submitButton">确 定</el-button>
      </div>
    </el-dialog>

    <!--流程任务接收-->
    <el-dialog
      title="选择任务接收"
      :visible.sync="assignOpen"
      :width="currentType === 'dept' ? '30%' : '65%'"
      :before-close="cancelAssignSelect"
      :close-on-press-escape="false"
      :destroy-on-close="true"
      append-to-body
    >
      <component :is="currentComponent" :selectData="selectData[currentType]" :suitType="bpmnFormData.assignType" @handleAssignSelect="handleAssignSelect"/>
      <span slot="footer" class="dialog-footer">
        <el-button size="mini" @click="cancelAssignSelect">取 消</el-button>
        <el-button size="mini" type="primary" @click="saveAssignSelect">确 认</el-button>
      </span>
    </el-dialog>
  </div>
</template>

<script>
import FlowAssignee from '@/components/Flow/Design/Assignee';
import FlowUsers from '@/components/Flow/Design/User';
import FlowRole from '@/components/Flow/Design/Role';
import FlowPost from '@/components/Flow/Design/Post';
import FlowDept from '@/components/Flow/Design/Dept';
import FlowExp from '@/components/Flow/Design/Expression';
import ElInputTag from '@/components/Flow/ElInputTag';
import {StrUtil} from '@/utils/StrUtil';
import {iconList} from "@/components/ElementIcon";
import {assignSelect} from "@/views/flowable/common/AssignUtils";
import CopyPanel from "@/components/Process/panel/copyPanel.vue";
import EventBus from '@/components/Process/common/EventBus'

export default {
  name: "UserTaskPanel",
  components: {
    CopyPanel,
    FlowAssignee,
    FlowUsers,
    FlowRole,
    FlowPost,
    FlowDept,
    FlowExp,
    ElInputTag
  },
  /** 组件传值  */
  props: {
    id: {
      type: String,
      required: true
    },
  },
  // 监听数据变化的组件
  mounted() {
    EventBus.$on('multiInstance-updated', (value) => {
      console.log('multiInstance-updated', value);
      this.multiInstanceTask = value;
      if (value){
        this.deleteFlowAttar();
        this.selectAssignList = [{id: this.multiInstanceAssign.id, name: this.multiInstanceAssign.name}];
        this.updateCustomElement('assignType', this.multiInstanceAssign.assignType);
        this.updateCustomElement('dataType', this.multiInstanceAssign.dataType);
        this.updateCustomElement('expId', this.multiInstanceAssign.id);
        const expression = "${" + this.id + "_assignee}";
        this.updateAssignElement(this.multiInstanceAssign.assignType, expression);
        this.handleSelectData("exp", this.multiInstanceAssign.id);
        this.bpmnFormData.assignType = this.multiInstanceAssign.assignType;
      } else {
        this.deleteFlowAttar();
        this.selectAssignList = [];
      }
    });
  },
  data() {
    return {
      iconList,
      editTag: [],
      assignOpen: false,
      isIndeterminate: true,
      checkType: 'single', // 选类
      assignType: '',
      assignTypeOption: [
        {label: '办理人', key: 'assignee', value: 'assignee'},
        {label: '候选人', key: 'users', value: 'candidateUsers'},
        {label: '角色', key: 'role', value: 'candidateGroups'},
        {label: '部门', key: 'dept', value: 'candidateGroups'},
        {label: '岗位', key: 'post', value: 'candidateGroups'},
      ],
      checkAll: false,
      buttonOption: [],
      buttonOptionList: [],
      bpmnFormData: {
        assignType: "assignee",
        assignee: null,
        candidateUsers: null,
        candidateGroups: null,
        priority: "",
        dataType: "",
        expId: "",
        writeExp: false,
        buttonList: [],
        $type: "",
        autoSkip: "false",
        timerType: 'timeDate',
        skipExpression: "",
        dueDate: "",
        timeDuration: {
          years: undefined,
          months: undefined,
          days: undefined,
          hours: undefined,
          minutes: undefined,
          seconds: undefined,
        },
      },
      // 数据回显
      selectData: {
        assignee: null,
        users: null,
        role: null,
        dept: null,
        post: null,
        exp: null,
      },
      otherExtensionList: [],
      bpmnElementButtonList: [],
      // 按钮编辑信息
      buttonForm: {},
      buttonDialogVisible: false,
      buttonSizeOptions: ['large', 'default', 'small'],
      buttonTypeOptions: ['primary', 'default', 'success', 'info', 'warning', 'danger'],
      selectAssignList: [], // 流程指定列表
      selectDataList: [], // 选择审核数据列表
      selectExpData: {}, // 选择表达式数据
      currentType: '', // 用于确定当前显示的组件
      expType: '', // 表达式类型
      assignButtonList: [
        {assignType: 'assignee', text: '指定用户', show: false, buttonType: 'primary', icon: 'el-icon-user'},
        {assignType: 'users', text: '候选用户', show: false, buttonType: 'primary', icon: 'el-icon-user'},
        {assignType: 'role', text: '候选角色', show: false, buttonType: 'primary', icon: 'el-icon-user'},
        {assignType: 'dept', text: '候选部门', show: false, buttonType: 'primary', icon: 'el-icon-user'},
        {assignType: 'post', text: '候选岗位', show: false, buttonType: 'primary', icon: 'el-icon-user'},
        {assignType: 'exp', text: '内置表达式', show: true, buttonType: 'warning', icon: 'el-icon-postcard'},
        {assignType: 'writeExp', text: '自定义表达式', show: true, buttonType: 'info', icon: 'el-icon-postcard'},
      ],
      startTaskAssign: {
        id: 1,
        name: '流程发起人',
        expression: '${INITIATOR}',
        dataType: 'fixed',
        assignType: 'assignee',
      },
      multiInstanceAssign: {
        id: 999,
        name: '会签人',
        dataType: 'fixed',
        assignType: 'assignee',
      },
      firstUserTask: false, // 是否是第一个用户任务节点
      multiInstanceTask: false, // 是否会签任务节点
      timerList: [
        { label: '指定时间', value: 'timeDate' },
        { label: '等待时长', value: 'timeDuration' },
        { label: '表达式', value: 'timeExp' },
      ],
    }
  },
  computed: {
    currentComponent() {
      return this.currentType ? `flow-${this.currentType}` : '';
    }
  },
  /** 传值监听 */
  watch: {
    id: {
      handler(newVal) {
        if (StrUtil.isNotBlank(newVal)) {
          this.resetTaskForm();
        }
      },
      immediate: true, // 立即生效
    },
  },
  created() {
  },
  methods: {
    // 初始化表单
    resetTaskForm() {
      const businessObject = this.modelerStore.element?.businessObject;
      this.buttonOption = JSON.parse(JSON.stringify(this.modelerStore.buttonOption));
      // 初始化设为空值
      this.bpmnFormData = {
        assignType: "assignee",
        assignee: null,
        candidateUsers: null,
        candidateGroups: null,
        timerType: '',
        dueDate: "",
        priority: "",
        dataType: "",
        expId: "",
        writeExp: false,
        buttonList: [],
        $type: "",
        autoSkip: "false",
        timeDuration: {
          years: undefined,
          months: undefined,
          days: undefined,
          hours: undefined,
          minutes: undefined,
          seconds: undefined,
        },
      }
      this.selectData = {
        assignee: null,
        users: null,
        role: null,
        dept: null,
        post: null,
        exp: null,
      }
      this.expType = '';
      this.selectAssignList = [];
      this.multiInstanceTask = false;
      // 流程节点信息上取值
      for (let key in this.bpmnFormData) {
        const value = businessObject[key] || this.bpmnFormData[key];
        this.$set(this.bpmnFormData, key, value);
      }

      // 过期时间回显
      this.getDueDateType(this.bpmnFormData);

      // 按钮回显
      this.resetButtonList();
      this.updateCustomElement('assignType', this.bpmnFormData.assignType);

      // 如果是第一个任务节点，设置默认审批人为流程发起人
      this.checkFirstUserTask(businessObject);
      if (this.firstUserTask) {
        this.selectAssignList = [{id: this.startTaskAssign.id, name: this.startTaskAssign.name}];
        this.updateCustomElement('dataType', this.startTaskAssign.dataType);
        this.updateCustomElement('expId', this.startTaskAssign.id);
        this.updateAssignElement(this.startTaskAssign.assignType, this.startTaskAssign.expression);
        this.handleSelectData("exp", this.startTaskAssign.id);
      }

      // 会签节点
      if (businessObject.loopCharacteristics){
        this.multiInstanceTask = true;
        this.selectAssignList = [{id: this.multiInstanceAssign.id, name: this.multiInstanceAssign.name}];
        this.updateCustomElement('dataType', this.multiInstanceAssign.dataType);
        this.updateCustomElement('expId', this.multiInstanceAssign.id);
        const expression = "${" + this.id + "_assignee}";
        this.updateAssignElement(this.multiInstanceAssign.assignType, expression);
        this.handleSelectData("exp", this.multiInstanceAssign.id);
      }

      // 人员信息回显
      if (!this.multiInstanceTask && !this.firstUserTask){
        this.checkValuesEcho(this.bpmnFormData);
      }
    },

    // 检验是否是第一个任务节点
    checkFirstUserTask(businessObject) {
      const process = businessObject.$parent;
      const isUserTask = businessObject.$type === 'bpmn:UserTask';

      if (process.routineTask) {
        const firstTask = process.flowElements.find(element => element.$type === 'bpmn:UserTask');
        this.firstUserTask = !firstTask || (isUserTask && businessObject.id === firstTask.id);
      } else {
        this.firstUserTask = false;
      }
    },


    // 更新节点信息
    updateElementTask(key) {
      const taskAttr = Object.create(null);
      taskAttr[key] = this.bpmnFormData[key] || "";
      this.modelerStore.modeling.updateProperties(this.modelerStore.element, taskAttr);
    },

    // 更新自定义流程节点/参数信息
    updateCustomElement(key, value) {
      const taskAttr = Object.create(null);
      taskAttr[key] = value;
      this.modelerStore.modeling.updateProperties(this.modelerStore.element, taskAttr);
    },

    // 更新审批人流程节点/参数信息
    updateAssignElement(assignType, value) {
      const key = this.getAssignValueByKey(assignType);
      const taskAttr = Object.create(null);
      taskAttr[key] = value;
      this.modelerStore.modeling.updateProperties(this.modelerStore.element, taskAttr);
    },

    // 更新人员类型
    changeAssignType(val) {
      // 删除xml中已选择数据类型节点
      this.deleteFlowAttar();
      // delete this.modelerStore.element.businessObject[`assignType`]
      // 清除已选人员数据
      this.bpmnFormData[val] = null;
      this.selectAssignList = [];
      this.selectData = {
        assignee: null,
        users: null,
        role: null,
        dept: null,
        post: null,
        exp: null,
      }
      // 写入assignType节点信息到xml
      this.updateCustomElement('assignType', val);
    },

    // 设计器右侧表单数据回显
    checkValuesEcho(formData) {
      if (formData.writeExp) {
        const assignValue = this.getAssignValueByKey(formData.assignType)
        const expValue = formData[assignValue];
        this.expType = 'writeExp';
        this.selectAssignList = [{value: expValue}];
      } else {
        if (StrUtil.isNotBlank(formData.expId)) {
          this.getExpList(formData.expId);
        } else {
          if (["role", "dept", "post"].includes(formData.assignType)) {
            this.getListByType(formData, `${formData.assignType}List`);
          } else {
            this.getUserList(formData);
          }
        }
      }
    },

    // 获取表达式信息
    getExpList(val) {
      if (StrUtil.isNotBlank(val)) {
        const expData = this.modelerStore.expList?.find(item => item.id.toString() === val);
        this.selectAssignList = [{id: expData.id, name: expData.name}];
        this.selectData.exp = expData.id;
      }
    },

    // 获取人员信息
    getUserList(formData) {
      const assignValue = this.getAssignValueByKey(formData.assignType)
      let val = formData[assignValue];
      if (StrUtil.isNotBlank(val)) {
        if (typeof val === "number") {
          val = val.toString();
        }
        const newArr = this.modelerStore.userList?.filter(i => val.split(',').includes(i.userId.toString()))
        this.updateSelectAssignList(newArr, "userId", "nickName", formData.assignType);
      }
    },

    // 统一的获取信息方法
    getListByType(formData, listType) {
      const assignValue = this.getAssignValueByKey(formData.assignType);
      let val = formData[assignValue];
      if (StrUtil.isNotBlank(val)) {
        if (typeof val === "number") {
          val = val.toString();
        }
        const newArr = this.modelerStore[listType]?.filter(i => val.split(',').includes(i[`${formData.assignType}Id`].toString()));
        this.updateSelectAssignList(newArr, `${formData.assignType}Id`, `${formData.assignType}Name`, formData.assignType);
      }
    },

    // 更新选择的分配列表
    updateSelectAssignList(data, idKey, nameKey, assignType) {
      this.selectAssignList = data.map(item => ({id: item[idKey], name: item[nameKey]}));
      if ("exp" === assignType || "assignee" === assignType || "dept" === assignType) {
        this.selectData[assignType] = data.map(item => item[idKey]).join(',');
      } else {
        this.selectData[assignType] = data;
      }
    },

    handleAssignSelect(selection) {
      if (selection) {
        if (this.currentType === 'exp') {
          // 处理表达式选中数据
          this.selectExpData = JSON.parse(JSON.stringify(selection));
        } else {
          // 处理审批选中数据
          this.selectDataList = JSON.parse(JSON.stringify(selection));
        }
      }
    },

    // 保存选中的数据
    saveAssignSelect() {
      if (this.currentType === 'exp') {
        const selection = this.selectExpData
        if (selection.id) {
          this.selectAssignList = [{id: selection.id, name: selection.name}];
          this.updateCustomElement('writeExp', false);
          this.updateCustomElement('dataType', selection.dataType);
          this.updateCustomElement('expId', selection.id.toString());
          this.updateAssignElement(this.bpmnFormData.assignType, selection.expression);
          this.handleSelectData("exp", selection.id);
        }
      } else {
        this.updateCustomElement('dataType', 'fixed');
        this.selectAssignList = JSON.parse(JSON.stringify(assignSelect(this.bpmnFormData.assignType,"", this.selectDataList)));
        // 更新xml数据
        this.updateAssignElement(this.bpmnFormData.assignType, this.selectAssignList.map(item => item.id).join(',') || '');
        if ("assignee" === this.bpmnFormData.assignType || "dept" === this.bpmnFormData.assignType) {
          this.handleSelectData(this.bpmnFormData.assignType, this.selectAssignList.map(item => item.id).join(',') || '');
        } else {
          this.handleSelectData(this.bpmnFormData.assignType, this.selectAssignList);
        }
      }
      this.expType = "";
      this.cancelAssignSelect();
    },

    // 取消任务审批数据
    cancelAssignSelect() {
      this.assignOpen = false;
    },

    // 处理审批按钮选中后切换不同组件
    handleAssignButtonClick(assignType) {
      if (assignType === 'writeExp') {
        this.deleteAssignAttar();
        this.expType = assignType;
        const expValue = "${" + this.id + "_assignee}";
        this.selectAssignList = [{value: expValue}];
        this.updateCustomElement('writeExp', true);
        this.updateCustomElement('dataType', 'dynamic');
        this.updateAssignElement(this.bpmnFormData.assignType, expValue);
      } else {
        this.currentType = assignType;
        this.assignOpen = true;
      }
    },

    // 处理人员回显
    handleSelectData(assignType, value) {
      for (let type in this.selectData) {
        if (assignType !== type) {
          this.$set(this.selectData, type, null);
        } else {
          this.$set(this.selectData, type, value);
        }
      }
    },

    /*根据选择的key获取选中指定审批类型的value*/
    getAssignValueByKey(key) {
      if (StrUtil.isBlank(key)) {
        return "";
      }
      return this.assignTypeOption.find(item => item.key === key).value;
    },

    /*移除选的审批人*/
    handleAssignClose(assign) {
      const index = this.selectAssignList.findIndex(item => item.id === assign.id);
      if (index !== -1) {
        this.selectAssignList.splice(index, 1);
        this.updateAssignElement(this.bpmnFormData.assignType, this.selectAssignList.map(item => item.id).join(',') || '');
        if ("exp" === this.bpmnFormData.assignType || "assignee" === this.bpmnFormData.assignType || "dept" === this.bpmnFormData.assignType) {
          this.handleSelectData(this.bpmnFormData.assignType, this.selectAssignList.map(item => item.id).join(',') || '');
        } else {
          this.handleSelectData(this.bpmnFormData.assignType, this.selectAssignList);
        }
      }
    },

    // 删除节点
    deleteFlowAttar() {
      delete this.modelerStore.element.businessObject[`dataType`]
      delete this.modelerStore.element.businessObject[`assignType`]
      delete this.modelerStore.element.businessObject[`expId`]
      delete this.modelerStore.element.businessObject[`assignee`]
      delete this.modelerStore.element.businessObject[`candidateUsers`]
      delete this.modelerStore.element.businessObject[`candidateGroups`]
      delete this.modelerStore.element.businessObject[`autoSkip`]
      delete this.modelerStore.element.businessObject[`writeExp`]
    },

    deleteAssignAttar() {
      delete this.modelerStore.element.businessObject[`expId`]
      delete this.modelerStore.element.businessObject[`assignee`]
      delete this.modelerStore.element.businessObject[`candidateUsers`]
      delete this.modelerStore.element.businessObject[`candidateGroups`]
    },

    resetButtonList() {
      this.bpmnElement = this.modelerStore.element;
      this.otherExtensionList = []; // 其他扩展配置
      const bpmnElementButtons =
          this.bpmnElement.businessObject?.extensionElements?.values?.filter(ex => {
            if (ex.$type !== `flowable:Buttons`) {
              this.otherExtensionList.push(ex);
            }
            if (ex.values) {
              return ex.$type === `flowable:Buttons`;
            }
          }) ?? [];

      if (bpmnElementButtons.length > 0) {
        // 保存所有的 扩展按钮字段
        this.bpmnElementButtonList = bpmnElementButtons.reduce((pre, current) => pre.concat(current.values), []);

        // 复制 显示
        const elementButtonList = JSON.parse(JSON.stringify(this.bpmnElementButtonList ?? []));
        // 读取节点上已配置的按钮节点
        this.buttonOption.forEach((button, index, arr) => {
          const elButton = elementButtonList.find(element => element.id === button.id)
          if (elButton) {
            arr[index] = elButton;
          }
        })
        this.bpmnFormData.buttonList = elementButtonList.map(item => item.id);
      }
    },

    handleCheckedButtonsChange(values) {
      if (values.length > 0) {
        // 当前选中的按钮
        const checkedButtons = this.buttonOption?.filter(i => values.includes(i.id))
        const newButtonList = [];
        checkedButtons.forEach(button => {
          const { id, label, code, icon, type, size, click } = button;
          const newButtonObject = this.modelerStore.moddle.create(`flowable:Button`, { id, label, code, icon, type, size, click});
          newButtonList.push(newButtonObject);
        })
        const buttonsObject = this.modelerStore.moddle.create(`flowable:Buttons`, {
          values: newButtonList
        });
        this.updateElementExtensions(buttonsObject);
        this.resetButtonList();
      } else {
        const buttonsObject = this.modelerStore.moddle.create(`flowable:Buttons`, {
          values: []
        });
        this.updateElementExtensions(buttonsObject);
      }
    },

    // 更新扩展属性信息
    updateElementExtensions(properties) {
      const extensions = this.modelerStore.moddle.create("bpmn:ExtensionElements", {
        values: this.otherExtensionList.concat([properties])
      });

      this.modelerStore.modeling.updateProperties(this.modelerStore.element, {
        extensionElements: extensions
      });
    },
    // 修改按钮信息
    editButton(button) {
      this.buttonDialogVisible = true;
      this.buttonForm = JSON.parse(JSON.stringify(button));
    },
    // 更新按钮信息
    submitButton() {
      // 找到下标后更改数据
      const index = this.buttonOption.findIndex(item => item.id === this.buttonForm.id);
      this.buttonOption[index] = this.buttonForm;
      // 替换选中的按钮
      const checkedButtons = this.buttonOption?.filter(i => this.bpmnFormData.buttonList.includes(i.id))
      const newButtonList = [];
      for (let button in  checkedButtons) {
        const { id, label, code, icon, type, size, click} = checkedButtons[button];
        const newButtonObject = this.modelerStore.moddle.create(`flowable:Button`, { id, label, code, icon, type, size, click});
        newButtonList.push(newButtonObject);
      }
      const buttonsObject = this.modelerStore.moddle.create(`flowable:Buttons`, {
        values: newButtonList
      });
      this.updateElementExtensions(buttonsObject);
      this.resetButtonList();
      this.buttonDialogVisible = false;
      this.buttonForm = {};
    },
    //编辑 input显示
    showEditTagInput(index) {
      this.$set(this.editTag, index, true);
      this.$nextTick((_) => {
        const editInput = "editInput" + index;
        this.$refs[editInput][0].$refs.input.focus();
      });
    },
    //编辑 input发生改变
    handleEditableInputConfirm(item, index) {
      if (item.value) {
        this.$set(this.editTag, index, false);
        this.selectAssignList = [{value: item.value}];
        this.updateAssignElement(this.bpmnFormData.assignType, item.value);
      } else {
        this.$modal.msgError( "请输入表达式");
      }
    },
    //编辑 input失去焦点
    handleEditableInputBlur(item, index) {
      this.$set(this.editTag, index, false);
    },

    // 设置dueDate时间类型
    changeTimeDuration() {
        this.bpmnFormData.dueDate = this.convertToISO8601(this.bpmnFormData.timeDuration);
        this.updateElementTask('dueDate');
    },

    // 转为ISO8601格式
    convertToISO8601(timeObj) {
      let duration = "P";
      if (timeObj.years) {
        duration += `${timeObj.years}Y`;
      }
      if (timeObj.months) {
        duration += `${timeObj.months}M`;
      }
      if (timeObj.days) {
        duration += `${timeObj.days}D`;
      }

      // 时间
      if (timeObj.hours || timeObj.minutes || timeObj.seconds) {
        duration += "T";

        if (timeObj.hours) {
          duration += `${timeObj.hours}H`;
        }
        if (timeObj.minutes) {
          duration += `${timeObj.minutes}M`;
        }
        if (timeObj.seconds) {
          duration += `${timeObj.seconds}S`;
        }
      }

      return duration;
    },

    // 切换到期时间类型
    handleTimerChange(val) {
      this.bpmnFormData.timerType = val;
      this.bpmnFormData.dueDate = '';
      delete this.modelerStore.element.businessObject[`dueDate`]
    },

    // 清空到期时间
    handleClearDueDate(){
      this.bpmnFormData.timerType = '';
      this.bpmnFormData.dueDate = '';
      delete this.modelerStore.element.businessObject[`dueDate`]
    },

    // 解析ISO8601格式
    parseISO8601(duration) {
      const regex = /P(?:(\d+)Y)?(?:(\d+)M)?(?:(\d+)D)?(?:T(?:(\d+)H)?(?:(\d+)M)?(?:(\d+)S)?)?/;
      const matches = duration.match(regex);

      return {
        years: matches[1] ? parseInt(matches[1]) : undefined,
        months: matches[2] ? parseInt(matches[2]) : undefined,
        days: matches[3] ? parseInt(matches[3]) : undefined,
        hours: matches[4] ? parseInt(matches[4]) : undefined,
        minutes: matches[5] ? parseInt(matches[5]) : undefined,
        seconds: matches[6] ? parseInt(matches[6]) : undefined
      };
    },

    // 获取到期时间类型
    getDueDateType(bpmnFormData) {
     if (bpmnFormData.dueDate) {
       if (bpmnFormData.dueDate.startsWith('${')) {
         bpmnFormData.timerType = 'timeExp';
       } else if (bpmnFormData.dueDate.startsWith('P')) {
         bpmnFormData.timerType = 'timeDuration';
         bpmnFormData.timeDuration = this.parseISO8601(bpmnFormData.dueDate);
       } else {
         bpmnFormData.timerType = 'timeDate';
       }
     } else {
       bpmnFormData.timerType = 'timeExp';
     }
    },
  }
}
</script>

<style>
.custom-switch .el-switch__label {
  position: absolute;
  display: none;
  color: #fff;
}
.custom-switch .el-switch__label * {
  font-size: 12px !important;
}
.custom-switch .el-switch__label--left {
  z-index: 9;
  left: 20px;
}
.custom-switch .el-switch__label--right {
  z-index: 9;
  left: 4px;
}
.custom-switch .el-switch__label.is-active {
  display: block;
}
.custom-switch .el-switch__core{
  width: 165px !important;
}

.inline-box {
  width: 300px;
}

.inline-box > div {
  margin-right: 5px;
}

.my-el-input-number[data-unit] {
  --el-input-number-unit-offset-x: 35px;
  position: relative;
  margin-top: 5px;
  margin-right: 5px;
  width: 90px;
}

.el-input-number .el-input__wrapper{
  padding-left: 0;
  padding-right: 0;
}

.el-input-number.is-controls-right .el-input__wrapper {
  padding-left: 0;
  padding-right: 0;
}

.my-el-input-number[data-unit]::after {
  content: attr(data-unit);
  height: 100%;
  display: flex;
  align-items: center;
  position: absolute;
  top: 0;
  right: var(--el-input-number-unit-offset-x);
  color: #999999;
}
.my-el-input-number[data-unit] .el-input__inner {
  padding-left: 20px;
  padding-right: calc(var(--el-input-number-unit-offset-x) + 12px);
}

</style>
